package com.github.cdisk.xtrans.ui.widget;

import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.EndOfLineRule;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.rules.IPredicateRule;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWhitespaceDetector;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.MultiLineRule;
import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WhitespaceRule;
import org.eclipse.jface.text.rules.WordRule;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.wb.swt.SWTResourceManager;

public class SqlTextDialog extends TextDialog {

	public static void main(String[] args) {
		Shell shell2 = new Shell();
		SqlTextDialog dialog = new SqlTextDialog(shell2, SWT.CLOSE);
		String result = dialog.open(null, "select * from dual");
		System.out.println(result);
	}

	public SqlTextDialog(Shell parent, int style) {
		super(parent, style);
	}

	/**
	 * Create contents of the dialog.
	 */
	@Override
	protected void createContents() {
		super.createContents();

		editor.configure(new SQLConfiguration());

		Document document = new Document();
		IDocumentPartitioner partitioner = new FastPartitioner(new SQLPartitionScanner(),
				new String[] { SQLPartitionScanner.SQL_COMMENT, SQLPartitionScanner.SQL_STRING, SQLPartitionScanner.SQL_PARAMETER });
		partitioner.connect(document);
		document.setDocumentPartitioner(partitioner);
		editor.setDocument(document);
	}

	public class SQLConfiguration extends SourceViewerConfiguration {

		public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
			return new String[] { IDocument.DEFAULT_CONTENT_TYPE, SQLPartitionScanner.SQL_COMMENT,
					SQLPartitionScanner.SQL_STRING, SQLPartitionScanner.SQL_PARAMETER };
		}

		private RuleBasedScanner getCommentScanner() {
			RuleBasedScanner scanner = new RuleBasedScanner();
//			EditorColorProvider colorProvider = Activator.getDefault().getEditorColorProvider();
//			scanner.setDefaultReturnToken(colorProvider.getToken(Activator.PREF_COLOR_COMMENT));
			scanner.setDefaultReturnToken(new Token(new TextAttribute(SWTResourceManager.getColor("008000"))));
			return scanner;
		}

		private RuleBasedScanner getStringScanner() {
			RuleBasedScanner scanner = new RuleBasedScanner();
//			EditorColorProvider colorProvider = Activator.getDefault().getEditorColorProvider();
//			scanner.setDefaultReturnToken(colorProvider.getToken(Activator.PREF_COLOR_STRING));
			scanner.setDefaultReturnToken(new Token(new TextAttribute(SWTResourceManager.getColor("0000FF"))));
			return scanner;
		}

		private RuleBasedScanner getDefaultScanner() {
			return new SQLKeywordPartitionScanner();
		}

		public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {

			PresentationReconciler reconciler = new PresentationReconciler();

			DefaultDamagerRepairer commentDR = new DefaultDamagerRepairer(getCommentScanner());
			reconciler.setDamager(commentDR, SQLPartitionScanner.SQL_COMMENT);
			reconciler.setRepairer(commentDR, SQLPartitionScanner.SQL_COMMENT);

			DefaultDamagerRepairer stringDR = new DefaultDamagerRepairer(getStringScanner());
			reconciler.setDamager(stringDR, SQLPartitionScanner.SQL_STRING);
			reconciler.setRepairer(stringDR, SQLPartitionScanner.SQL_STRING);

			DefaultDamagerRepairer paramterDR = new DefaultDamagerRepairer(getStringScanner());
			reconciler.setDamager(paramterDR, SQLPartitionScanner.SQL_PARAMETER);
			reconciler.setRepairer(paramterDR, SQLPartitionScanner.SQL_PARAMETER);

			DefaultDamagerRepairer keywordDR = new DefaultDamagerRepairer(getDefaultScanner());
			reconciler.setDamager(keywordDR, IDocument.DEFAULT_CONTENT_TYPE);
			reconciler.setRepairer(keywordDR, IDocument.DEFAULT_CONTENT_TYPE);

			return reconciler;
		}
	}

	/**
	 * 关键词分词
	 * 
	 * @author Administrator
	 *
	 */
	public static class SQLKeywordPartitionScanner extends RuleBasedScanner {

		private static String[] KEYWORDS = { "select", "update", "insert", "into", "delete", "from", "where", "values",
				"set", "order", "by", "left", "outer", "inner", "join", "having", "group", "create", "alter", "drop",
				"table", "like", "limit", "with", "asc", "desc" };

		public SQLKeywordPartitionScanner() {
//			IToken keyword = Activator.getDefault().getEditorColorProvider().getToken(Activator.PREF_COLOR_KEYWORD);
			IToken keyword = new Token(new TextAttribute(SWTResourceManager.getColor("800080")));
//			IToken other = Activator.getDefault().getEditorColorProvider().getToken(Activator.PREF_COLOR_DEFAULT);
			IToken other = new Token(new TextAttribute(SWTResourceManager.getColor("000000")));

			WordRule wordRule = new WordRule(new IWordDetector() {
				public boolean isWordPart(char c) {
					return Character.isJavaIdentifierPart(c);
				}

				public boolean isWordStart(char c) {
					return Character.isJavaIdentifierStart(c);
				}
			}, other);
			for (int i = 0; i < KEYWORDS.length; i++) {
				wordRule.addWord(KEYWORDS[i], keyword);
				wordRule.addWord(KEYWORDS[i].toUpperCase(), keyword);
			}
			IRule[] rules = new IRule[2];
			rules[0] = wordRule;
			rules[1] = new WhitespaceRule(new IWhitespaceDetector() {
				public boolean isWhitespace(char character) {
					return Character.isWhitespace(character);
				}
			});

			setRules(rules);
		}

	}

	/**
	 * 用于SQL编辑分区，区分字符串或者注释
	 * 
	 * @author Administrator
	 *
	 */
	public class SQLPartitionScanner extends RuleBasedPartitionScanner {

		public static final String SQL_COMMENT = "__sql_comment";
		public static final String SQL_STRING = "__sql_string";
		public static final String SQL_PARAMETER = "__sql_parameter";

		public SQLPartitionScanner() {
			IPredicateRule[] rules = new IPredicateRule[5];

			IToken comment = new Token(SQL_COMMENT);
			rules[0] = new MultiLineRule("/*", "*/", comment, (char) 0, true);
			rules[1] = new EndOfLineRule("--", comment);

			IToken string = new Token(SQL_STRING);
			rules[2] = new SingleLineRule("\"", "\"", string, '\\');
			rules[3] = new SingleLineRule("\'", "\'", string, '\\');

			IToken parameter = new Token(SQL_PARAMETER);
			rules[4] = new SingleLineRule("${", "}", parameter, '\\');

			setPredicateRules(rules);
		}

	}
}
